﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using HighDiveAdmin.Handlers;
using HighDiveAdmin.Resources;

namespace HighDiveAdmin.Engine
{
    /// <summary>
    ///Class for contest management
    /// </summary>
    public class Contest
    {
        #region Properties

        /// <summary>
        /// DatabaseId
        /// </summary>
        public int? DbId { get; set; }
        public string Name { get; set; }
        public string Date { get; set; }
        public string Club { get; set; }
        public string City { get; set; }
        public string Country { get; set; }

        /// <summary>
        /// ContestStatus determines whether the competition is Unstarted / Started / Finished
        /// </summary>
        public ContestStatus Status { get; set; }

        /// <summary>
        /// List of the contest judges
        /// </summary>
        public JudgeList JudgeList { get; set; }

        /// <summary>
        /// Queue of future jumpers. This list is empty when the contest ended.
        /// </summary>
        public DiveList DiveQueue { get; set; }

        /// <summary>
        /// History of the performed jumps. This list is full when the contest ended.
        /// </summary>
        public DiveList DiveHistory { get; set; }

        #endregion

        #region Public methods

        /// <summary>
        /// Add a new convictions or points 
        /// update an already set points
        /// Check if JudgeScore list is complete, if so then               
        /// call TotalScore().
        /// </summary>
        public void UpdateJudgeScore(Dive dive, string judgeidString, double judgescore)
        {
            var index = JudgeList.FindIndex(x => x.IdString.Equals(judgeidString));
            dive.JudgeScore[index] = judgescore;
            if (CheckScoreComplete(dive))
            {
                dive.CalculateTotalScore();

                //if dive is the current active dive, call UpdateDiveQueue()
                if (DiveQueue.Count != 0 && dive.Equals(DiveQueue[0]))
                {
                    UpdateDiveQueue();
                }
            }
        }

        /// <summary>
        /// Moves the first dive in the dive queue into the dive history.
        /// </summary>
        public void UpdateDiveQueue()
        {
            DiveHistory.Add((DiveQueue[0]));
            DiveQueue.RemoveAt(0);
        }

        #endregion

        #region Private methods

        /// <summary>
        /// Checks that all judge scores have been entered for a dive
        /// </summary>
        /// <param name="dive">The dive which to check</param>
        /// <returns>true if all scores have been entered, otherwise false</returns>
        private bool CheckScoreComplete(Dive dive)
        {
            for (int i = 0; i < JudgeList.NumberOfJudges; i++)
            {
                if (dive.JudgeScore[i] == null)
                {
                    return false;
                }
            }
            return true;
        }        
        
        #endregion

        #region Constructors

        public Contest()
        {

        }

        /// <summary>
        /// Creates a new contest.
        /// </summary>
        public Contest(string name, string date, string club, int numberOfJudges, string city = null, string country = null)
        {
            Name = name;
            Date = date;
            Club = club;
            City = city;
            Country = country;
            Status = ContestStatus.Unstarted;
            JudgeList = new JudgeList(numberOfJudges);
            DiveQueue = new DiveList();
            DiveHistory = new DiveList();
            DbId = null;
        }

        #endregion
    }
}
